﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

namespace Utility
{
    public class Collections
    {
        [XmlRoot("dictionary")]
        public class SerializableDictionary<TKey, TValue>
            : Dictionary<TKey, TValue>, IXmlSerializable
        {
            #region IXmlSerializable Members
            public System.Xml.Schema.XmlSchema GetSchema()
            {
                return null;

            }

            public void ReadXml(System.Xml.XmlReader reader)
            {
                XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));

                XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));



                bool wasEmpty = reader.IsEmptyElement;

                reader.Read();



                if (wasEmpty)
                {
                    return;
                }

                reader.ReadStartElement("dictionary");
                while ((reader.NodeType != System.Xml.XmlNodeType.EndElement) && (reader.NodeType != System.Xml.XmlNodeType.None))
                {
                    reader.ReadStartElement("item");



                    reader.ReadStartElement("key");
                    TKey key = (TKey)keySerializer.Deserialize(reader);
                    reader.ReadEndElement();



                    reader.ReadStartElement("value");

                    TValue value = (TValue)valueSerializer.Deserialize(reader);

                    reader.ReadEndElement();


                    try
                    {
                        this.Add(key, value);
                    }
                    catch { }


                    reader.ReadEndElement();

                    reader.MoveToContent();

                }

                if (reader.NodeType != System.Xml.XmlNodeType.None) reader.ReadEndElement();

            }



            public void WriteXml(System.Xml.XmlWriter writer)
            {


                XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
                XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));


                writer.WriteStartElement("dictionary");
                foreach (TKey key in this.Keys)
                {

                    writer.WriteStartElement("item");



                    writer.WriteStartElement("key");

                    keySerializer.Serialize(writer, key);

                    writer.WriteEndElement();



                    writer.WriteStartElement("value");

                    TValue value = this[key];

                    valueSerializer.Serialize(writer, value);

                    writer.WriteEndElement();



                    writer.WriteEndElement();

                }
                writer.WriteEndElement();
            }

            #endregion

        }

        [XmlRoot("list")]
        public class SerializableList<T>
            : List<T>, IXmlSerializable
        {
            #region IXmlSerializable Members
            public System.Xml.Schema.XmlSchema GetSchema()
            {
                return null;
            }



            public void ReadXml(System.Xml.XmlReader reader)
            {
                XmlSerializer keySerializer = new XmlSerializer(typeof(T));

                bool wasEmpty = reader.IsEmptyElement;

                reader.Read();



                if (wasEmpty)

                    return;


                reader.ReadStartElement("list");
                while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
                {
                    reader.ReadStartElement("key");
                    T key = (T)keySerializer.Deserialize(reader);
                    reader.ReadEndElement();

                    this.Add(key);

                    reader.MoveToContent();

                }
                reader.ReadEndElement();

            }



            public void WriteXml(System.Xml.XmlWriter writer)
            {

                XmlSerializer keySerializer = new XmlSerializer(typeof(T));

                writer.WriteStartElement("list");
                foreach (T key in this)
                {
                    writer.WriteStartElement("key");
                    keySerializer.Serialize(writer, key);
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
            }

            #endregion

        }


        [XmlRoot("hashset")]
        public class SerializableHashSet<T>
            : List<T>, IXmlSerializable
        {
            #region IXmlSerializable Members
            public System.Xml.Schema.XmlSchema GetSchema()
            {
                return null;
            }



            public void ReadXml(System.Xml.XmlReader reader)
            {
                XmlSerializer keySerializer = new XmlSerializer(typeof(T));

                bool wasEmpty = reader.IsEmptyElement;

                reader.Read();



                if (wasEmpty)

                    return;


                reader.ReadStartElement("hashset");
                while (!((reader.NodeType == System.Xml.XmlNodeType.EndElement) || (reader.NodeType == System.Xml.XmlNodeType.None)))
                {
                    reader.ReadStartElement("key");
                    if (reader.NodeType != System.Xml.XmlNodeType.EndElement)
                    {
                        T key = (T)keySerializer.Deserialize(reader);
                        reader.ReadEndElement();
                        this.Add(key);
                    }



                    reader.MoveToContent();

                }
                //reader.ReadEndElement();
            }



            public void WriteXml(System.Xml.XmlWriter writer)
            {

                XmlSerializer keySerializer = new XmlSerializer(typeof(T));

                writer.WriteStartElement("hashset");
                foreach (T key in this)
                {
                    writer.WriteStartElement("key");
                    keySerializer.Serialize(writer, key);
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
            }

            #endregion

        }

    }
}
